#include "Test_Time.h"

#include <QtTest/QtTest>

#include "Time.h"

#include <thread>

void Test_Time::test_timing()
{
    // Creamos un reloj con el cual contar.
    Time time([](){});

    /// Verficamos que sus valores esten en cero.
    unsigned int zero
            = static_cast<unsigned int>(0);
    QCOMPARE(time.seconds(), zero);
    QCOMPARE(time.minutes(), zero);
    QCOMPARE(time.hours(), zero);

    /// Verificamos que pueda contar 1 seg.
    // Iniciamos el reloj.
    time.start();

    // Esperamos a que pase un segundo.
    std::this_thread::sleep_for(
                std::chrono::milliseconds(1500));

    // Verificamos que esta contando.
    QCOMPARE(time.counting(), true);

    // Detenemos el reloj.
    time.pause();

    // Verificamos que no este contando.
    QCOMPARE(time.counting(), false);

    // Verificamos que si se conto el segundo.
    unsigned int one
            = static_cast<unsigned int>(1);
    QCOMPARE(time.seconds(), one);
    QCOMPARE(time.minutes(), zero);
    QCOMPARE(time.hours(), zero);

    /// Verificamos que se pueda contar mas de 1 seg.
    time.start();

    // Esperamos a que pase otro segundo.
    std::this_thread::sleep_for(
                std::chrono::milliseconds(1500));

    // Detenemos el reloj.
    time.pause();

    // Verificamos que si se contro el otro segundo.
    QCOMPARE(time.seconds(), one + 1);
    QCOMPARE(time.minutes(), zero);
    QCOMPARE(time.hours(), zero);

    /// Verificamos que la funcion restart
    /// detiene y reinicia los valores del reloj.
    time.restart();

    // Verficiamos que el reloj no esta contando.
    QCOMPARE(time.counting(), false);

    // Verificamos que los valores estan en cero.
    QCOMPARE(time.seconds(), zero);
    QCOMPARE(time.minutes(), zero);
    QCOMPARE(time.hours(), zero);
}

void Test_Time::test_tick()
{
    // Indicamos que no se ha ejecutado el ticked.
    bool ticked = false;

    // Creamos el reloj y establecemos el cambio
    // para indicar que el ticked se ejecuto.
    Time time([&]()
    {
        ticked = true;
    }); // En este momento: ticked = false.

    // Iniciamos el reloj.
    time.start();

    // Esperamos a que pase un segundo
    // y ejecute la funcion tick.
    std::this_thread::sleep_for(
                std::chrono::milliseconds(1500));

    // Detenemos el reloj.
    time.pause();

    // Verificamos que se ejecuto el ticked.
    QCOMPARE(ticked, true);
}

void Test_Time::test_changes()
{
    /// Establecemos la funcion inicial.
    // Indicamos que no se ha ejecutado el ticked.
    bool ticked = false;

    // Creamos el reloj y establecemos el cambio
    // para indicar que el ticked se ejecuto.
    Time time([&]()
    {
        ticked = true;
    });

    /// Intentamos cambiar la funcion tick
    /// al estar corriendo el reloj.
    // Iniciamos el reloj.
    time.start();

    // Intentamos modificar el tick a pesar
    // de que el reloj esta corriendo.
    time.setTick([](){});

    // Esperamos a que termine.
    std::this_thread::sleep_for(
                std::chrono::milliseconds(1500));

    // Deteneos el reloj.
    time.pause();

    /// Arrancamos una vez mas el reloj despues
    /// de que se intento cambiar la funcion tick.
    // Reiniciamos el valor ticked puesto que si
    // no se modifico el tick esta bandera nos
    // lo hara saber.
    ticked = false;

    /// Arrancamos el reloj y ejecutamos el tick.
    time.start();
    std::this_thread::sleep_for(
                std::chrono::milliseconds(1500));
    time.pause();

    /// Si la bandera ticked cambio es porque
    /// el tick sigue siendo el mismo.
    QCOMPARE(ticked, true);
}
